home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / language / fplib20.arc / SOURCES.ARC / FPMUL.S < prev    next >
Text File  |  1987-04-22  |  3KB  |  112 lines

  1. * Copyright (c) 1988 by Sozobon, Limited.  Author: Johann Ruegg
  2. *
  3. * Permission is granted to anyone to use this software for any purpose
  4. * on any computer system, and to redistribute it freely, with the
  5. * following restrictions:
  6. * 1) No charge may be made other than reasonable charges for reproduction.
  7. * 2) Modified versions must be clearly marked as such.
  8. * 3) The authors are not responsible for any harmful consequences
  9. *    of using this software, even if they result from defects in it.
  10. *
  11. * MODIFICATION:
  12. *
  13. * D.W.Brooks    Apr 89    Tightened up some coding, and looked after some
  14. *            trailing bits for the sake of textbook rounding.
  15. *
  16. *    fpmul
  17. *
  18.     .globl    _fpmult
  19.     .globl    _fpmul
  20.     .globl    fpmul
  21. fpmul:
  22. _fpmul:
  23. _fpmult:
  24.     move.l    d3,a0        * save scratch registers
  25.     move.l    d4,a1
  26.     move.l    d5,a2
  27.     move.l    4(sp),d0
  28.     move.l    8(sp),d1
  29.  
  30.     move.l    #$7F,d2        * Calculate the presumed exponent
  31.     move.l    d2,d3
  32.     and.w    d0,d2
  33.     beq    ret        * Mult by 0: d0 is correct
  34.     and.w    d1,d3
  35.     beq    ret0        * Mult by 0: set d0
  36.     add.w    d3,d2
  37.     sub.w    #$40,d2        * Remove the extra bias
  38.  
  39.     clr.b    d0        * Calculate the absolute mantissa product
  40.     clr.b    d1
  41.     move.w    d0,d3        * Get least significant bits of result
  42.     mulu.w    d1,d3
  43.     swap    d3        * d3 range now 0...fe01
  44.  
  45.     move.w    d0,d4
  46.     move.w    d1,d5
  47.     swap    d0
  48.     swap    d1
  49.     mulu    d0,d5        * calculate inner portion
  50.     mulu    d1,d4
  51.     add.l    d3,d4        * no carry since d3 <= fe01 && d4 <= fffe0001
  52.     add.l    d4,d5
  53.     bcc    nocar1
  54.     move.w    d5,d3        * Save trailing bits
  55.     move.w    #1,d5
  56.     bra    t1
  57. nocar1:
  58.     move.w    d5,d3
  59.     clr.w    d5
  60. t1:
  61.     swap    d5
  62.  
  63.     mulu    d1,d0        * calculate most significant part
  64.     add.l    d5,d0
  65.     bcc    nocar2
  66.     roxr.l    #1,d0
  67.     addq.w    #1,d2        * Normalize down
  68. nocar2:
  69.     bmi    norm
  70.     add.l    d0,d0        * only need at most 1 shift: started norm AB
  71.     subq.w    #1,d2
  72. norm:
  73.     add.l    #$80,d0        * Round uppppp....
  74.     bcc    nocar3
  75.     roxr.l    #1,d0
  76.     addq.w    #1,d2
  77. nocar3:
  78.     tst.b    d0        * Check if trailer was exactly 0x80 (now 0x00)
  79.     bne    rebuild
  80.     tst.w    d3        * Check back with spare bits
  81.     bne    rebuild
  82.     and.w    #$FE00,d0    * Round to even
  83. rebuild:
  84.     tst.w    d2        * Reconstruct the number.  First test overflow
  85.     ble    underflow    * Could be mult by 0
  86.     cmp.w    #$7F,d2
  87.     bgt    overflow
  88. expsign:
  89.     move.b    d2,d0        * Stuff exponent in
  90.     move.b    7(sp),d1    * Calculate sign
  91.     move.b    11(sp),d2
  92.     eor.b    d1,d2
  93.     and.b    #$80,d2
  94.     or.b    d2,d0
  95. ret:
  96.     move.l    a2,d5
  97.     move.l    a1,d4
  98.     move.l    a0,d3
  99.     rts
  100.  
  101. ret0:
  102. underflow:
  103.     move.l    #0,d0        * Underflow, return 0
  104.     bra    ret
  105.  
  106. overflow:
  107.     move.l    #$7F,d2        * Overflow, return +/- huge
  108.     move.l    #$FFFFFFFF,d0
  109.     bra    expsign
  110.  
  111.     .end
  112.